package com.xcs.wx.repository.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xcs.wx.constant.DataSourceType;
import com.xcs.wx.domain.Contact;
import com.xcs.wx.domain.dto.ContactDTO;
import com.xcs.wx.domain.vo.AllContactVO;
import com.xcs.wx.domain.vo.ContactVO;
import com.xcs.wx.domain.vo.ExportContactVO;
import com.xcs.wx.mapper.ContactMapper;
import com.xcs.wx.repository.ContactRepository;
import org.springframework.stereotype.Repository;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 联系人 Repository 实现类
 * 实现ContactRepository接口，提供联系人数据的访问和操作功能
 * 
 * @author xcs
 * @date 2023年12月22日 14时21分
 **/
@Repository // 将该类标识为仓储类的组件
@DS(value = DataSourceType.MICRO_MSG_DB) // 指定使用的数据源
public class ContactRepositoryImpl extends ServiceImpl<ContactMapper, Contact> implements ContactRepository {

    /**
     * 查询联系人列表
     *
     * @param contactDTO 查询参数
     * @return 分页后的联系人视图对象
     */
    @Override
    public Page<ContactVO> queryContact(ContactDTO contactDTO) {
        // 调用MyBatis-Plus的查询方法，分页查询联系人
        return getBaseMapper().queryContact(new Page<>(contactDTO.getCurrent(), contactDTO.getPageSize()), contactDTO);
    }

    /**
     * 查询所有联系人
     *
     * @return 所有联系人的列表
     */
    @Override
    public List<AllContactVO> queryAllContact() {
        // 查询所有联系人并过滤掉昵称为空的记录
        return getBaseMapper().queryAllContact().stream().filter(contactVO -> !contactVO.getNickName().isEmpty()).collect(Collectors.toList());
    }

    /**
     * 根据用户名查询联系人昵称
     *
     * @param userName 用户名
     * @return 对应的联系人昵称或备注
     */
    @Override
    public String getContactNickname(String userName) {
        // 构建查询条件
        LambdaQueryWrapper<Contact> wrapper = Wrappers.<Contact>lambdaQuery()
                .select(Contact::getUserName, Contact::getNickName, Contact::getRemark)
                .eq(Contact::getUserName, userName);
        // 查询数据库
        Contact contact = super.getOne(wrapper);

        // 空校验
        if (contact == null) {
            return "未知用户";
        }

        // 如果备注不为空则取备注，否则取联系人的昵称
        return StrUtil.isNotBlank(contact.getRemark()) ? contact.getRemark() : contact.getNickName();
    }

    /**
     * 根据用户名查询昵称
     *
     * @param userName 用户名
     * @return 对应的昵称
     */
    @Override
    public String getNickName(String userName) {
        // 构建查询条件
        LambdaQueryWrapper<Contact> wrapper = Wrappers.<Contact>lambdaQuery()
                .select(Contact::getNickName)
                .eq(Contact::getUserName, userName);
        // 查询数据库并获取结果
        return Optional.ofNullable(super.getOne(wrapper))
                .map(Contact::getNickName)
                .orElse(null);
    }

    /**
     * 获取具有公众号的联系人
     *
     * @return 具有公众号的联系人集合
     */
    @Override
    public Set<String> getContactWithMp() {
        // 查询并返回具有公众号的联系人
        return getBaseMapper().getContactWithMp();
    }

    /**
     * 根据用户名列表查询联系人昵称
     *
     * @param userNames 用户名列表
     * @return 用户名与联系人昵称或备注的映射关系
     */
    @Override
    public Map<String, String> getContactNickname(List<String> userNames) {
        // 构建查询条件
        LambdaQueryWrapper<Contact> wrapper = Wrappers.<Contact>lambdaQuery()
                .select(Contact::getUserName, Contact::getNickName, Contact::getRemark)
                .in(Contact::getUserName, userNames);
        // 查询数据库
        Map<String, String> contactMap = Optional.ofNullable(super.list(wrapper))
                .map(contacts -> contacts.stream().collect(Collectors.toMap(Contact::getUserName, contact -> StrUtil.isNotBlank(contact.getRemark()) ? contact.getRemark() : contact.getNickName())))
                .orElse(Collections.emptyMap());

        // 返回用户映射关系
        return userNames.stream().collect(Collectors.toMap(item -> item, item -> {
            String nickName = contactMap.get(item);
            // 空校验
            if (StrUtil.isBlank(nickName)) {
                return "未知用户";
            }
            // 如果备注不为空则取备注，否则取联系人的昵称
            return nickName;
        }));
    }

    /**
     * 统计联系人数量
     *
     * @return 联系人数量
     */
    @Override
    public int countContact() {
        // 调用Mapper方法统计联系人数量
        return getBaseMapper().countContact();
    }

    /**
     * 导出联系人信息
     *
     * @return 导出信息列表
     */
    @Override
    public List<ExportContactVO> exportContact() {
        // 调用Mapper方法导出联系人信息
        return getBaseMapper().exportContact();
    }
}
